/**
 * Copyright (c) 2015-2017, Henry Yang 杨勇 (gismail@foxmail.com).
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.lambkit.module.cms.rpc.service.impl;

import java.util.List;

import com.jfinal.kit.Kv;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Page;
import com.jfinal.plugin.activerecord.SqlPara;
import com.lambkit.common.service.LambkitModelServiceImpl;
import com.lambkit.core.aop.AopKit;
import com.lambkit.db.sql.column.Columns;
import com.lambkit.db.sql.column.Example;
import com.lambkit.db.sql.condition.ConditionBuilder;
import com.lambkit.db.sql.condition.SqlBuilder;
import com.lambkit.module.cms.rpc.api.CmsArticleService;
import com.lambkit.module.cms.rpc.model.CmsArticle;
import com.lambkit.module.cms.rpc.model.CmsTag;

/**
 * @author yangyong 
 * @website: www.lambkit.com
 * @email: gismail@foxmail.com
 * @date 2019-10-22
 * @version 1.0
 * @since 1.0
 */
public class CmsArticleServiceImpl extends LambkitModelServiceImpl<CmsArticle> implements CmsArticleService {
	
	private CmsArticle DAO = null;
	
	public CmsArticle dao() {
		if(DAO==null) {
			DAO = AopKit.singleton(CmsArticle.class);
		}
		return DAO;
	}

	@Override
	public Page<CmsArticle> paginateByCategoryId(Integer pageNumber, Integer pageSize, Long categoryId) {
		// TODO Auto-generated method stub
		SqlPara sqlPara = dao().getSqlPara("cms.selectCmsArticlesByCategoryId", categoryId);
		return dao().paginate(pageNumber, pageSize, sqlPara);
	}

	@Override
	public Page<CmsArticle> paginateByTagId(Integer pageNumber, Integer pageSize, Long tagId) {
		// TODO Auto-generated method stub
		CmsTag tag = CmsTag.service().findById(tagId);
		if(tag!=null) {
			Kv cond = Kv.by("tagName", tag.getName()).set("status", CmsArticle.STATUS_NORMAL);
			SqlPara sqlPara = dao().getSqlPara("cms.selectCmsArticlesByTag", cond);
			return dao().paginate(pageNumber, pageSize, sqlPara);
		}
		return null;
	}
	
	@Override
	public Page<CmsArticle> paginateByTag(Integer pageNumber, Integer pageSize, String tag) {
		// TODO Auto-generated method stub
		Kv cond = Kv.by("tagName", tag).set("status", CmsArticle.STATUS_NORMAL);
		SqlPara sqlPara = dao().getSqlPara("cms.selectCmsArticlesByTag", cond);
		return dao().paginate(pageNumber, pageSize, sqlPara);
	}
	
	@Override
	public Page<CmsArticle> paginateByUserTag(Integer pageNumber, Integer pageSize, Long userId, String tag) {
		// TODO Auto-generated method stub
		Kv cond = Kv.by("tagName", tag).set("userId", userId).set("status", CmsArticle.STATUS_NORMAL);
		SqlPara sqlPara = dao().getSqlPara("cms.selectCmsArticlesByTag", cond);
		return dao().paginate(pageNumber, pageSize, sqlPara);
	}

	@Override
	public Page<CmsArticle> paginateInNormal(Integer pageNumber, Integer pageSize, String orderBy) {
		// TODO Auto-generated method stub
		Example example = CmsArticle.sql().andStatusEqualTo(CmsArticle.STATUS_NORMAL).example();
		example.setOrderBy(orderBy);
		Page<CmsArticle> dataPage = paginate(pageNumber, pageSize, example);
		return joinForView(dataPage);
	}

	@Override
	public CmsArticle findFirstByAlias(String alias) {
		// TODO Auto-generated method stub
		Example example = CmsArticle.sql().andAliasEqualTo(alias).example();
		return findFirst(example);
	}

	@Override
	public Page<CmsArticle> search(Integer pageNumber, Integer pageSize, String keyword) {
		Columns columns = Columns.create("status", CmsArticle.STATUS_NORMAL)
                .likeAppendPercent("title", keyword);
        return joinForView(paginateByColumns(pageNumber, pageSize, columns, "order_number desc,id desc"));
	}

	@Override
	public List<CmsArticle> findListByCategoryId(Long categoryId, String orderBy, Integer count) {
		// TODO Auto-generated method stub
		Kv cond = Kv.by("categoryId", categoryId).set("orderby", orderBy).set("status", CmsArticle.STATUS_NORMAL);
		SqlPara sqlPara = dao().getSqlPara("cms.findCmsArticlesByCategoryId", cond);
		return dao().find(sqlPara, count);
	}

	@Override
	public Page<CmsArticle> paginateByCategoryIdInNormal(Integer pageNumber, Integer pageSize, Long categoryId, String orderBy) {
		Kv cond = Kv.by("categoryId", categoryId).set("orderby", orderBy).set("status", CmsArticle.STATUS_NORMAL);
		SqlPara sqlPara = dao().getSqlPara("cms.findCmsArticlesByCategoryId", cond);
		Page<CmsArticle> dataPage = dao().paginate(pageNumber, pageSize, sqlPara);
		return joinForView(dataPage);
	}

	@Override
	public CmsArticle findNextById(Long articleId) {
		Example example = CmsArticle.sql().andArticleIdGreaterThan(articleId)
				.andStatusEqualTo(CmsArticle.STATUS_NORMAL).example();
		example.setOrderBy("article_id");
		return findFirst(example);
	}

	@Override
	public CmsArticle findPreviousById(Long articleId) {
		Example example = CmsArticle.sql().andArticleIdLessThan(articleId)
				.andStatusEqualTo(CmsArticle.STATUS_NORMAL).example();
		example.setOrderBy("article_id desc");
		return findFirst(example);
	}

	@Override
	public List<CmsArticle> findRelevantListByArticleId(Long articleId, Integer status, Integer count) {
		CmsArticle article = CmsArticle.service().findById(articleId);
		if(article==null || StrKit.isBlank(article.getTag())) {
			return null;
		}
		String tag = article.getTag();
		if(tag.startsWith(",")) tag = tag.substring(1);
		if(tag.endsWith(",")) tag = tag.substring(0, tag.length()-1);
		String[] tags = tag.split(",");
        Kv cond = Kv.by("tags", tags).set("status", status);
        SqlPara sqlPara = dao().getSqlPara("cms.findRelevantListByArticleId", cond);
        return dao().find(sqlPara, count);
	}

	@Override
	public List<CmsArticle> findListByTagId(Long tagId, String orderBy, Integer count) {
		CmsTag tag = CmsTag.service().findById(tagId);
		if(tag!=null) {
			Kv cond = Kv.by("tagName", tag.getName()).set("orderby", orderBy).set("status", CmsArticle.STATUS_NORMAL);
			SqlPara sqlPara = dao().getSqlPara("cms.findListByTag", cond);
			return dao().find(sqlPara, count);
		}
		return null;		
	}
	
	@Override
	public List<CmsArticle> findListByTag(String tag, String orderBy, Integer count) {
		Kv cond = Kv.by("tagName", tag).set("orderby", orderBy).set("status", CmsArticle.STATUS_NORMAL);
		SqlPara sqlPara = dao().getSqlPara("cms.findListByTag", cond);
		return dao().find(sqlPara, count);
	}
	
	@Override
	public Page<CmsArticle> paginateViewByConditions(Integer pageNumber, Integer pageSize, ConditionBuilder cb,
			String orderBy) {
		// TODO Auto-generated method stub
		SqlPara sqlPara = dao().getSqlPara("cms.selectArticleViewList");
		SqlBuilder sb = new SqlBuilder();
		sb.clear().appendConditions(cb.build("a."));
		if(StrKit.notBlank(orderBy)) sb.appendOrderBy(orderBy);
		String sql = sb.build();
		sqlPara.setSql(sqlPara.getSql() + " where 1=1 " + sql);
		List<Object> paras = cb.getParamList();
		for (int i = 0; i < paras.size(); i++) {
			sqlPara.addPara(paras.get(i));
		}
		return dao().paginate(pageNumber, pageSize, sqlPara);
	}

	
	private Page<CmsArticle> joinForView(Page<CmsArticle> vals) {
		for (CmsArticle article : vals.getList()) {
			article.joinUser();
			article.joinForView();
		}
		return vals;
	}
	
}
